package com.sinodata.bsm.center.bean;

import java.util.ArrayList;
import java.util.List;

import com.sinodata.bsm.center.cache.ResAttrValCache;
import com.sinodata.bsm.center.cache.ResCache;
import com.sinodata.bsm.center.util.spring.SpringContextHolder;
import com.sinodata.bsm.common.vo.Res;
import com.sinodata.bsm.common.vo.ResAttrVal;

/**
 * 
 * <p>
 * Description: 资源业务对象
 * </p>
 * 
 * @author liulibo
 * @version 1.0
 * 
 * <p>
 * History:
 * 
 * Date Author Version Description
 * ---------------------------------------------------------------------------------
 * 2012-5-24 PM 2:33:52 liulibo 1.0 To create
 * </p>
 * 
 * @since
 * @see
 */
public class ResBean {

    /**
     * 资源缓存
     */
    private static ResCache resCache = SpringContextHolder.getBean(ResCache.class);

    /**
     * 资源属性缓存
     */
    private static ResAttrValCache resAttrValCache = SpringContextHolder.getBean(ResAttrValCache.class);

    /**
     * 资源POJO对象
     */
    private Res res;

    /**
     * 资源类别业务对象
     */
    private ResTypeBean resTypeBean;

    /**
     * 默认构造方法，不推荐使用
     * 
     */
    private ResBean() {

    }

    /**
     * 构造方法，构建资源业务对象
     * 
     * @param res
     */
    private ResBean(Res res) {
        this.res = res;
    }

    /**
     * 获取一个资源的业务对象
     * 
     * @param resId
     * @return
     */
    public static ResBean get(Long resId) {
        Res res = resCache.get(resId);
        if (res != null) {
            return new ResBean(res);
        }
        return null;
    }

    /**
     * 返回POJO资源对象
     * 
     * @return
     */
    public Res res() {
        return res;
    }

    /**
     * 获取资源类型
     * 
     * @return
     */
    public ResTypeBean type() {
        if (resTypeBean == null) {
            resTypeBean = ResTypeBean.get(res.getResTypeId());
        }
        return resTypeBean;
    }

    /**
     * 获取资源的子资源
     * 
     * @return
     */
    public ResBean[] children() {
        List<ResBean> children = RelationHelper.children(this.res.getId());
        return children.toArray(new ResBean[children.size()]);
    }

    /**
     *获取资源的父资源
     * @return
     */
    public List<ResBean> parents() {
        return RelationHelper.parents(this.res.getId());
    }

    /**
     * 获取一个资源下 特定类别的子资源 只找一层 不递归
     * 
     * @param resTypeId
     * @return
     */
    public ResBean[] childrenByType(Long resTypeId) {
        List<ResBean> children = RelationHelper.children(this.res.getId());
        List<ResBean> typeChild = new ArrayList<ResBean>();
        for (ResBean rb : children) {
            if (rb.res.getResTypeId().equals(resTypeId)) {
                typeChild.add(rb);
            }
        }
        return typeChild.toArray(new ResBean[typeChild.size()]);
    }

    /**
     * 获得不超过depth代的子孙资源，
     * 
     * @param depth
     * @return
     * @author hehaiyang_itsm (用于性能图指标计算)
     */
    public List<ResBean> descents(int depth) {
        List<ResBean> ret = new ArrayList<ResBean>();
        if (depth == 0) {
            return ret;
        }
        List<ResBean> children = RelationHelper.children(this.res.getId());
        ret.addAll(children);
        for (ResBean rb : children) {
            ret.addAll(rb.descents(--depth));
        }
        return ret;
    }

    /**
     * 获取特定类别的子孙资源
     * 
     * @param resTypeId ,
     *            depth
     * @return
     * @author hehaiyang_itsm (用于性能图指标计算)
     */
    public List<ResBean> descentsByType(Long resTypeId, int depth) {
        if (depth == 0) {
            return new ArrayList<ResBean>();
        }
        List<ResBean> children = RelationHelper.children(this.res.getId());
        List<ResBean> typeChild = new ArrayList<ResBean>();
        for (ResBean rb : children) {
            if (rb.res.getResTypeId().equals(resTypeId)) {
                typeChild.add(rb);
            }
            typeChild.addAll(rb.descentsByType(resTypeId, --depth));
        }
        return typeChild;
    }

    /**
     * 根据唯一标示(internalId)找一个子资源对象
     * 
     * @param resTypeId
     * @param internalId
     * @return
     */
    public ResBean child(Long resTypeId, String internalId) {
        List<ResBean> children = RelationHelper.children(this.res.getId());
        for (ResBean resBean : children) {
            if (internalId.equals(resBean.res().getInternalId())) {
                return resBean;
            }
        }
        return null;
    }

    /**
     * 是否是叶子资源节点
     * 
     * @return
     */
    public boolean isLeaf() {
        return RelationHelper.children(this.res.getId()).size() == 0;
    }

    /**
     * 判断该资源是否resId所代表的资源的后代资源。
     * 
     * @param resId
     * @return
     */
    public boolean isDescendant(Long resId) {
        List<ResBean> parents = RelationHelper.parents(this.res.getId());
        if (parents.size() == 0) {
            return false;
        }
        for (int i = 0; i < parents.size(); i++) {
            if (parents.get(i).res().getId() == resId || parents.get(i).isDescendant(resId)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 得到该资源的一个属性的值。
     */
    public ResAttrVal resAttrVal(Long attributeId) {
        return resAttrValCache.get(this.res.getId(), attributeId);
    }

}